﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using xn;
using WobbrockLib;
using WobbrockLib.Extensions;
using System.IO;

namespace KinectAPI.Gestures.Dollar
{
    public class Dollar : Gesture
    {
        private BodyTracker body;
        private BodyGestureGenerator bgg;
        private Dictionary<uint, List<TimePointF>> users;

        private const int MinNoPoints = 70;
        private Recognizer _rec;

        public event EventHandler Start;

        public event EventHandler End;

        public event EventHandler Recognised;

        public string getName()
        {
            return "Dollar"; ;
        }

        public Dollar()
        {
        }

        public void construct(object[] args)
        {
            bgg = (BodyGestureGenerator)args[1];
            body = (BodyTracker)args[0];
            body.UsersUpdated += new BodyTracker.UsersUpdatedHandler(Users_Updated);

            _rec = new Recognizer();
            LoadGesture((string[])args[2]);

            users = new Dictionary<uint, List<TimePointF>>();
        }

        void LoadGesture(string[] args)
        {
            bool all = false;
            if (args[0].CompareTo("All") == 0)
            {
                all = true;
            }
            DirectoryInfo info = new DirectoryInfo(@"..\..\plugins\xml");
            foreach (DirectoryInfo dir in info.GetDirectories())
            {
                foreach (FileInfo file in dir.GetFiles("*.xml"))
                {
                    if (all || args.Contains(file.Name.Substring(0, file.Name.Length-6)))
                    {
                        System.Console.WriteLine("load " + dir.Name + "\\" + file.Name);
                        _rec.LoadGesture(file.FullName);
                    }
                }
            }
        }

        void Users_Updated(object sender, UsersEventArgs e)
        {
            foreach (var user in e.users)
            {
                if (!users.ContainsKey(user.Id))
                {
                    users.Add(user.Id, new List<TimePointF>());
                }

                // TODO
                if (users[user.Id].Count() == MinNoPoints)
                {
                    users[user.Id].RemoveAt(0);
                }
                users[user.Id].Add(new TimePointF(user.RightHand.X, user.RightHand.Y, TimeEx.NowMs));

                if (users[user.Id].Count >= MinNoPoints)
                {
                    if (_rec.NumGestures > 0)
                    {
                        NBestList result = _rec.Recognize(users[user.Id], false);
                        if(result.Score >= 0.85)
                        {
                            users[user.Id].Clear();
                            Recognised(this, new GestureEventArgs(getName(), new object[]{result.Name, result.Score}));
                        }
                    }
                }
            }
        }
    }
}
